package com.leyou.item.service;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.leyou.common.enums.ExceptionEnum;
import com.leyou.common.exceptions.LyException;
import com.leyou.common.utils.BeanHelper;
import com.leyou.common.vo.PageResult;
import com.leyou.item.dto.*;
import com.leyou.item.entity.Sku;
import com.leyou.item.entity.Spu;
import com.leyou.item.entity.SpuDetail;
import com.leyou.item.mappers.DetailMapper;
import com.leyou.item.mappers.Skumapper;
import com.leyou.item.mappers.SpuMapper;
import org.apache.commons.lang3.StringUtils;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import tk.mybatis.mapper.entity.Example;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static com.leyou.common.constants.MQConstants.Exchange.ITEM_EXCHANGE_NAME;
import static com.leyou.common.constants.MQConstants.RoutingKey.ITEM_DOWN_KEY;
import static com.leyou.common.constants.MQConstants.RoutingKey.ITEM_UP_KEY;

/**
 * @Auther: xiang
 * @Date: 2019/8/18 21:03
 * @Description:
 */
@Service
@Transactional
public class GoodsService {

    @Autowired
    private SpuMapper spuMapper;
    @Autowired
    private CategoryService categoryService;
    @Autowired
    private BrandService brandService;
    @Autowired
    private DetailMapper detailMapper;
    @Autowired
    private Skumapper skuMapper;
    @Autowired
    private AmqpTemplate amqpTemplate;

    public PageResult<SpuDTO> querySpuByPage(Integer page, Integer rows, Boolean saleable, String key) {
        Page<Object> objects = PageHelper.startPage(page, rows);
        Example example = new Example(Spu.class);
        Example.Criteria criteria = example.createCriteria();
        if (StringUtils.isNotBlank(key)) {
            criteria.andLike("name", "%" + "%");
        }
        if (saleable != null) {
            criteria.andEqualTo("saleable", saleable);
        }
        //没传上架信息默认按照时间排序
        example.setOrderByClause("update_time DESC");
        List<Spu> spuList = spuMapper.selectByExample(example);
        if (spuList.size() == 0) {
            throw new LyException(ExceptionEnum.GOODS_NOT_FOUND);
        }

        List<SpuDTO> spuDTOList = BeanHelper.copyWithCollection(spuList, SpuDTO.class);
        // 5 处理分类名称和品牌名称
        handleCategoryAndBrandName(spuDTOList);
        return new PageResult<>(objects.getTotal(), spuDTOList);

    }

    /**
     * 处理spu的分类名称和品牌名称
     *
     * @param spuDTOList
     */
    private void handleCategoryAndBrandName(List<SpuDTO> spuDTOList) {
        for (SpuDTO spuDTO : spuDTOList) {
            String categoryName = categoryService.queryCategoryByids(spuDTO.getCategoryIds()).stream().map(CategoryDTO::getName).collect(Collectors.joining("/"));
            spuDTO.setCategoryName(categoryName);
            BrandDTO brandDTO = brandService.queryById(spuDTO.getBrandId());
            spuDTO.setBrandName(brandDTO.getName());

        }
    }

    public void saveGoods(SpuDTO spuDTO) {
        //保存商品逻辑
        //从dto取出数据
        Spu spu = BeanHelper.copyProperties(spuDTO, Spu.class);
        //保存spu,默认下架,新增的商品默认是下架的
        spu.setSaleable(false);
        int insert = spuMapper.insertSelective(spu);
        if (insert == 0) {
            throw new LyException(ExceptionEnum.INSERT_OPERATION_FAIL);
        }
        //保存spudetail
        SpuDetailDTO spuDetailDTO = spuDTO.getSpuDetail();
        SpuDetail spuDetail = BeanHelper.copyProperties(spuDetailDTO, SpuDetail.class);
        spuDetail.setSpuId(spu.getId());
        int insert1 = detailMapper.insertSelective(spuDetail);
        if (insert == 0) {

            throw new LyException(ExceptionEnum.INSERT_OPERATION_FAIL);
        }
        //获得sku数据
        List<SkuDTO> skuDTOS = spuDTO.getSkus();
        List<Sku> skuList = BeanHelper.copyWithCollection(skuDTOS, Sku.class);
        for (Sku sku : skuList) {
            sku.setSpuId(spu.getId());
            sku.setEnable(false);

        }
        int i = skuMapper.insertList(skuList);
        if (i != skuList.size()) {
            throw new LyException(ExceptionEnum.INSERT_OPERATION_FAIL);
        }

    }

    public void updateSaleable(Long id, Boolean saleable) {
        //更新spu
        Spu spu = new Spu();
        spu.setId(id);
        spu.setSaleable(false);
        int i = spuMapper.updateByPrimaryKeySelective(spu);
        if (i == 0) {
            throw new LyException(ExceptionEnum.UPDATE_OPERATION_FAIL);
        }
//同时也应该更新sku,一个spu对应这多个sku,spu下架对应sku也下架
        Sku sku = new Sku();
        sku.setEnable(saleable);
        //准备更新的匹配条件
        Example example = new Example(Sku.class);
        example.createCriteria().andEqualTo("spuId", id);
        int i1 = skuMapper.updateByExampleSelective(sku, example);
        // 发送mq消息
        String key = saleable ? ITEM_UP_KEY : ITEM_DOWN_KEY;
        amqpTemplate.convertAndSend(ITEM_EXCHANGE_NAME, key, id);
        int size = skuMapper.selectCountByExample(example);
        if (i1 != size) {
            throw new LyException(ExceptionEnum.UPDATE_OPERATION_FAIL);

        }

    }

    /**
     * 根据spuId查询spuDetail
     *
     * @param id
     * @return
     */
    public SpuDetailDTO querySpuDetail(Long id) {

        SpuDetail spuDetail = detailMapper.selectByPrimaryKey(id);
        if (spuDetail == null) {
            throw new LyException(ExceptionEnum.GOODS_NOT_FOUND);

        }
        return BeanHelper.copyProperties(spuDetail, SpuDetailDTO.class);


    }

    /**
     * 通过spuid查询sku
     *
     * @param id
     * @return
     */

    public List<SkuDTO> querySku(Long id) {
        Sku sku = new Sku();
        sku.setSpuId(id);

        List<Sku> select = skuMapper.select(sku);
        if (CollectionUtils.isEmpty(select)) {

            throw new LyException(ExceptionEnum.GOODS_NOT_FOUND);

        }
        return BeanHelper.copyWithCollection(select, SkuDTO.class);


    }

    /**
     * 根据id修改
     */
    public void updateGoods(SpuDTO spuDTO) {
        //根据传的spudto,把spu删了再加
        Long id = spuDTO.getId();
        if (id == null) {

            throw new LyException(ExceptionEnum.INVALID_NOTIFY_PARAM);
        }

        //先删除sku
        Sku sku = new Sku();
        sku.setSpuId(id);
        int skus = skuMapper.selectCount(sku);
        if (skus == 0) {

            throw new LyException(ExceptionEnum.UPDATE_OPERATION_FAIL);
        }
        int skuNum = skuMapper.delete(sku);


        if (skuNum != skus) {
            throw new LyException(ExceptionEnum.UPDATE_OPERATION_FAIL);

        }
        //更新spu
        Spu spu = BeanHelper.copyProperties(spuDTO, Spu.class);
        spu.setSaleable(false);
        spu.setUpdateTime(null);
        spu.setCreateTime(null);
        int i = spuMapper.updateByPrimaryKeySelective(spu);
        if (i != 1) {
            throw new LyException(ExceptionEnum.UPDATE_OPERATION_FAIL);

        }
        //更新spudetail
        SpuDetailDTO spuDetailDTO = spuDTO.getSpuDetail();
        SpuDetail spuDetail = BeanHelper.copyProperties(spuDetailDTO, SpuDetail.class);
        spuDetail.setCreateTime(null);
        spuDetail.setUpdateTime(null);
        int count = detailMapper.updateByPrimaryKeySelective(spuDetail);
        if (count != 1) {
            throw new LyException(ExceptionEnum.UPDATE_OPERATION_FAIL);
        }
        // 4.新增sku
        List<SkuDTO> skuDTOList = spuDTO.getSkus();
        List<Sku> skuList = BeanHelper.copyWithCollection(skuDTOList, Sku.class);
        for (Sku sku1 : skuList) {
            sku1.setSpuId(spu.getId());
            // 下架状态
            sku1.setEnable(false);
        }
        count = skuMapper.insertList(skuList);
        if (count != skuList.size()) {
            throw new LyException(ExceptionEnum.INSERT_OPERATION_FAIL);
        }
    }

    /**
     * 通过spuid查询spu ，返回spu，但是我们还要用spudetail
     * 和sku，这两个都是通过spuid查到的吗，所以字啊一个接口中
     * 我们完成了三个查询。
     *
     * @param id
     * @return
     */
    public SpuDTO querySpuById(Long id) {
        //查询spu
        Spu spu = spuMapper.selectByPrimaryKey(id);
        SpuDTO spuDTO = BeanHelper.copyProperties(spu, SpuDTO.class);
        //查询spuDetail
        spuDTO.setSpuDetail(querySpuDetail(id));
        //查询sku
        spuDTO.setSkus(querySku(id));
        return spuDTO;
    }

    /**
     * 查询sku集合
     *
     * @param ids
     * @return
     */
    public List<SkuDTO> querySkuList(List<Long> ids) {
        // 查询sku
        List<Sku> skuList = skuMapper.selectByIdList(ids);
        if (CollectionUtils.isEmpty(skuList)) {
            throw new LyException(ExceptionEnum.GOODS_NOT_FOUND);
        }
        return BeanHelper.copyWithCollection(skuList, SkuDTO.class);

    }

    @Transactional
    public void minusStock(Map<Long, Integer> cartMap) {
        //减库存
        for (Map.Entry<Long, Integer> entry : cartMap.entrySet()) {
            Long key = entry.getKey();
            Integer value = entry.getValue();
            int i = skuMapper.minusStock(key, value);
            if (i != 1) {
                throw new RuntimeException("库存不足");
            }


        }

    }
}